﻿/* **************************************************************************
 *
 * Copyright 2007-2010 Jeff Hardy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * *************************************************************************/

using System.Collections;
using Microsoft.Web.Administration;
using Microsoft.Web.Management.Server;

namespace NWSGI.Management
{
    internal class NwsgiModuleService : ModuleService
    {
        private WsgiSection wsgi;
        private WsgiSection Wsgi
        {
            get
            {
                if(this.wsgi == null)
                    this.wsgi = (WsgiSection)ManagementUnit.Configuration.GetSection("wsgi", typeof(WsgiSection));

                return this.wsgi;
            }
        }

        [ModuleServiceMethod]
        public PropertyBag GetConfiguration()
        {
            PropertyBag bag = new PropertyBag
            {
                {(int)PropertyKeys.EnableExtensionsKey, Wsgi.EnableExtensions},
                {(int)PropertyKeys.WildcardPhysicalPathKey, Wsgi.Wildcard.PhysicalPath},
                {(int)PropertyKeys.WildcardCallableKey, Wsgi.Wildcard.Callable},
                {(int)PropertyKeys.CompilationKey, (int)Wsgi.Compilation},
                {(int)PropertyKeys.FramesKey, (int)Wsgi.Frames},
                {(int)PropertyKeys.TracingKey, Wsgi.Tracing},
                {(int)PropertyKeys.LightweightScopesKey, Wsgi.LightweightScopes},
                {(int)PropertyKeys.EnableProfilerKey, Wsgi.EnableProfiler},
            };

            return bag;
        }

        [ModuleServiceMethod]
        public void UpdateConfiguration(PropertyBag bag)
        {
            foreach(PropertyKeys k in bag.ModifiedKeys)
            {
                switch(k)
                {
                    case PropertyKeys.EnableExtensionsKey:
                        if(Wsgi.EnableExtensions != (bool)bag[(int)PropertyKeys.EnableExtensionsKey])
                            Wsgi.EnableExtensions = (bool)bag[(int)PropertyKeys.EnableExtensionsKey];
                        break;

                    case PropertyKeys.CompilationKey:
                        if(Wsgi.Compilation != (CompilationOptions)(int)bag[(int)PropertyKeys.CompilationKey])
                            Wsgi.Compilation = (CompilationOptions)(int)bag[(int)PropertyKeys.CompilationKey];
                        break;

                    case PropertyKeys.FramesKey:
                        if(Wsgi.Frames != (FrameOptions)(int)bag[(int)PropertyKeys.FramesKey])
                            Wsgi.Frames = (FrameOptions)(int)bag[(int)PropertyKeys.FramesKey];
                        break;

                    case PropertyKeys.TracingKey:
                        if(Wsgi.Tracing != (bool)bag[(int)PropertyKeys.TracingKey])
                            Wsgi.Tracing = (bool)bag[(int)PropertyKeys.TracingKey];
                        break;

                    case PropertyKeys.LightweightScopesKey:
                        if(Wsgi.LightweightScopes != (bool)bag[(int)PropertyKeys.LightweightScopesKey])
                            Wsgi.LightweightScopes = (bool)bag[(int)PropertyKeys.LightweightScopesKey];
                        break;

                    case PropertyKeys.EnableProfilerKey:
                        if(Wsgi.EnableProfiler != (bool)bag[(int)PropertyKeys.EnableProfilerKey])
                            Wsgi.EnableProfiler = (bool)bag[(int)PropertyKeys.EnableProfilerKey];
                        break;

                    case PropertyKeys.WildcardPhysicalPathKey:
                        if(Wsgi.Wildcard.PhysicalPath != (string)bag[(int)PropertyKeys.WildcardPhysicalPathKey])
                            Wsgi.Wildcard.PhysicalPath = (string)bag[(int)PropertyKeys.WildcardPhysicalPathKey];
                        break;

                    case PropertyKeys.WildcardCallableKey:
                        if(Wsgi.Wildcard.Callable != (string)bag[(int)PropertyKeys.WildcardCallableKey])
                            Wsgi.Wildcard.Callable = (string)bag[(int)PropertyKeys.WildcardCallableKey];
                        break;
                }
            }

            base.ManagementUnit.Update();
        }

        #region PythonPaths

        [ModuleServiceMethod]
        public ArrayList GetPythonPaths()
        {
            ArrayList paths = new ArrayList();
            foreach(PythonPathInfo path in Wsgi.PythonPaths)
            {
                paths.Add(path.Path);
            }

            return paths;
        }

        [ModuleServiceMethod]
        public void AddPythonPath(string path)
        {
            Wsgi.PythonPaths.Add(new PythonPathInfo { Path = path });
            base.ManagementUnit.Update();
        }

        [ModuleServiceMethod]
        public void EditPythonPath(string oldPath, string newPath)
        {
            foreach(PythonPathInfo pathInfo in Wsgi.PythonPaths)
            {
                if(pathInfo.Path == oldPath)
                {
                    pathInfo.Path = newPath;
                    base.ManagementUnit.Update();
                    return;
                }
            }
        }

        [ModuleServiceMethod]
        public void DeletePythonPath(string path)
        {
            PythonPathInfo target = null;
            foreach(PythonPathInfo pathInfo in Wsgi.PythonPaths)
            {
                if(pathInfo.Path == path)
                    target = pathInfo;
            }

            if(target != null)
            {
                Wsgi.PythonPaths.Remove(target);
                base.ManagementUnit.Update();
            }
        }

        #endregion

        #region WsgiEnviron

        [ModuleServiceMethod]
        public ArrayList GetWsgiEnviron()
        {
            ArrayList variables = new ArrayList();
            foreach(WsgiEnvironElement variable in Wsgi.WsgiEnviron)
            {
                variables.Add(new string[] { variable.Name, variable.Value });
            }

            return variables;
        }

        [ModuleServiceMethod]
        public void AddWsgiEnvironVariable(string[] values)
        {
            string name = values[0];
            string value = values[1];

            WsgiEnvironElement e = Wsgi.WsgiEnviron.CreateElement();
            e.Name = name;
            e.Value = value;

            Wsgi.WsgiEnviron.Add(e);
            base.ManagementUnit.Update();
        }

        [ModuleServiceMethod]
        public void EditWsgiEnvironVariable(string[] values)
        {
            string name = values[0];
            string value = values[1];

            foreach(WsgiEnvironElement variable in Wsgi.WsgiEnviron)
            {
                if(variable.Name == name)
                {
                    variable.Value = value;
                    base.ManagementUnit.Update();
                    return;
                }
            }
        }

        [ModuleServiceMethod]
        public void DeleteWsgiEnvironVariable(string name)
        {
            foreach(WsgiEnvironElement variable in Wsgi.WsgiEnviron)
            {
                if(variable.Name == name)
                {
                    Wsgi.WsgiEnviron.Remove(variable);
                    base.ManagementUnit.Update();
                    return;
                }
            }
        }

        #endregion

        #region ScriptMappings

        [ModuleServiceMethod]
        public ArrayList GetScriptMappings()
        {
            ArrayList paths = new ArrayList();
            foreach(ScriptMappingElement mapping in Wsgi.ScriptMappings)
            {
                paths.Add(new string[] { mapping.ScriptName, mapping.PhysicalPath, mapping.Callable });
            }

            return paths;
        }

        [ModuleServiceMethod]
        public void AddScriptMapping(string[] values)
        {
            ScriptMappingElement mapping = Wsgi.ScriptMappings.CreateElement();
            mapping.ScriptName = values[0];
            mapping.PhysicalPath = values[1];
            mapping.Callable = values[2];

            Wsgi.ScriptMappings.Add(mapping);
            base.ManagementUnit.Update();
        }

        [ModuleServiceMethod]
        public void EditScriptMapping(string[] values)
        {
            foreach(ScriptMappingElement mapping in Wsgi.ScriptMappings)
            {
                if(mapping.ScriptName == values[0])
                {
                    mapping.PhysicalPath = values[1];
                    mapping.Callable = values[2];

                    base.ManagementUnit.Update();
                    return;
                }
            }
        }

        [ModuleServiceMethod]
        public void DeleteScriptMapping(string scriptName)
        {
            ScriptMappingElement target = null;
            foreach(ScriptMappingElement mapping in Wsgi.ScriptMappings)
            {
                if(mapping.ScriptName == scriptName)
                    target = mapping;
            }

            if(target != null)
            {
                Wsgi.ScriptMappings.Remove(target);
                base.ManagementUnit.Update();
            }
        }

        #endregion
    }
}
